﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.Revit;
using YArchitech.Temp;

namespace YArchitech.Plumbing
{
	public class SetSanitaryHelper
	{
		public SetSanitaryHelper(UIDocument uiDoc)
		{
			this.doc = uiDoc.Document;
			this.sel = uiDoc.Selection;
			this.uiDoc = uiDoc;
		}

		public Element GetSanitary()
		{
			Element result;
			try
			{
				string prompt = "请选择一个洁具";
				Element element;
				for (;;)
				{
					element = this.uiDoc.PickElementsByPoint(prompt, 0.05).Element;
					if (DbUtils.IsPlumbingFixtures(element))
					{
						break;
					}
					prompt = "当前选择的不是洁具，请重新选择一个洁具";
				}
				List<Element> list = new List<Element>();
				list.Add(element);
				RevitVersionFuncs.SetSelection(this.sel, list);
				result = element;
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				result = null;
			}
			return result;
		}

		public XYZ GetPoint(string strPoint, Element elem)
		{
			XYZ result;
			try
			{
				if (elem == null)
				{
					YJKMessageBox.Show("请先选择洁具");
					result = null;
				}
				else
				{
					XYZ xyz = (elem.Location as LocationPoint).Point;
					if (elem.Document.IsLinked)
					{
						xyz = this.doc.GetLinkedDocument(elem.Id).GetPointInLinkDocument(xyz);
					}
					XYZ xyz2 = this.sel.PickPoint("请点选" + strPoint + "点");
					XYZ xyz3 = new XYZ((xyz2 - xyz).X, (xyz2 - xyz).Y, 0.0);
					if (xyz3.IsAlmostEqualTo(new XYZ(0.0, 0.0, 0.0)))
					{
						xyz3 = new XYZ(1E-05, 1E-05, 0.0);
					}
					result = xyz3;
				}
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				result = null;
			}
			return result;
		}

		public void WriteExtendData(SetSanitaryData setSanitaryData, Element elem)
		{
			string szScName = "NewSanitaryPara";
			Schema schema = this.CreateSchema(szScName, elem.Document.IsLinked);
			List<Element> listElem = this.GetListElem(elem);
			if (listElem != null)
			{
				foreach (Element element in listElem)
				{
					Entity entity = this.GetEntity(setSanitaryData, elem, schema);
					element.SetEntity(entity);
				}
			}
			this.WriteLinkExtendData(setSanitaryData, elem);
		}

		private void WriteLinkExtendData(SetSanitaryData setSanitaryData, Element elem)
		{
			if (!elem.Document.IsLinked)
			{
				return;
			}
			string szScName = YJKRevitTools.HYBathroomPre + (elem as FamilyInstance).Symbol.Family.Name;
			Schema schema = this.CreateSchema(szScName, true);
			Entity entity = this.GetEntity(setSanitaryData, elem, schema);
			this.doc.ProjectInformation.SetEntity(entity);
		}

		private Schema CreateSchema(string szScName, bool beLinkedDocument)
		{
			szScName = YJKRevitTools.CheckSchemaName(szScName);
			Schema schema = null;
			if (beLinkedDocument)
			{
				IEnumerator<Schema> enumerator = Schema.ListSchemas().GetEnumerator();
				{
					while (enumerator.MoveNext())
					{
						Schema schema2 = enumerator.Current;
						if (schema2.SchemaName == szScName)
						{
							schema = schema2;
						}
					}
					goto IL_50;
				}
			}
			schema = Schema.Lookup(YJKRevitTools.SanitaryGuid);
			IL_50:
			if (schema == null)
			{
				Guid guid = YJKRevitTools.SanitaryGuid;
				if (beLinkedDocument)
				{
					guid = Guid.NewGuid();
				}
				SchemaBuilder schemaBuilder = new SchemaBuilder(guid);
                schemaBuilder.SetReadAccessLevel((AccessLevel)1);
                schemaBuilder.SetWriteAccessLevel((AccessLevel)1);
				schemaBuilder.SetSchemaName(szScName);
				schemaBuilder.SetDocumentation("Data store for socket related info in a Sanitary");
				schema = this.GetSchema(schemaBuilder, guid);
			}
			return schema;
		}

		private List<Element> GetListElem(Element elem)
		{
			List<Element> result;
			try
			{
				List<Element> list = new List<Element>();
				if (!(elem is FamilyInstance))
				{
					result = list;
				}
				else
				{
					FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.doc);
					filteredElementCollector.OfCategory(BuiltInCategory.OST_PlumbingFixtures);
					filteredElementCollector.OfClass(typeof(FamilyInstance));
					foreach (Element element in filteredElementCollector)
					{
						FamilyInstance familyInstance = elem as FamilyInstance;
						if (familyInstance != null && (element as FamilyInstance).Symbol.Family.Name.Equals(familyInstance.Symbol.Family.Name))
						{
							list.Add(element);
						}
					}
					result = list;
				}
			}
			catch (Exception)
			{
				result = null;
			}
			return result;
		}

		private Schema GetSchema(SchemaBuilder builder, Guid guid)
		{
			builder.AddSimpleField(SanitaryPara.SanitaryType.ToString(), typeof(string));
			builder.AddSimpleField(SanitaryPara.HotPointVector.ToString(), typeof(XYZ)).SetUnitType(0);
			builder.AddSimpleField(SanitaryPara.ColdPointVector.ToString(), typeof(XYZ)).SetUnitType(0);
			builder.AddSimpleField(SanitaryPara.PointOffset.ToString(), typeof(double)).SetUnitType(0);
			builder.AddSimpleField(SanitaryPara.ColdOffset.ToString(), typeof(double)).SetUnitType(0);
			builder.AddSimpleField(SanitaryPara.HotOffset.ToString(), typeof(double)).SetUnitType(0);
			builder.AddSimpleField(SanitaryPara.Trap.ToString(), typeof(int));
			builder.AddSimpleField(SanitaryPara.DrainEquivalent.ToString(), typeof(double)).SetUnitType(0);
			builder.AddSimpleField(SanitaryPara.DrainFlow.ToString(), typeof(double)).SetUnitType(0);
			builder.AddSimpleField(SanitaryPara.FeedEquivalent.ToString(), typeof(double)).SetUnitType(0);
			builder.AddSimpleField(SanitaryPara.FeedFlow.ToString(), typeof(double)).SetUnitType(0);
			builder.AddSimpleField(SanitaryPara.HotAngle.ToString(), typeof(double)).SetUnitType(0);
			builder.AddSimpleField(SanitaryPara.ColdAngle.ToString(), typeof(double)).SetUnitType(0);
			builder.AddSimpleField(SanitaryPara.ShortName.ToString(), typeof(string));
			builder.AddSimpleField(SanitaryPara.fieldNew.ToString(), typeof(string));
			builder.AddSimpleField("New1", typeof(string));
			builder.AddSimpleField("New2", typeof(string));
			builder.AddSimpleField("New3", typeof(string));
			builder.AddSimpleField("New4", typeof(string));
			builder.AddSimpleField("New5", typeof(string));
			Schema result;
			try
			{
				result = builder.Finish();
			}
			catch (Exception)
			{
				result = Schema.Lookup(guid);
			}
			return result;
		}

		private Entity GetEntity(SetSanitaryData setSanitaryData, Element elem, Schema schema)
		{
			Entity entity = new Entity(schema);
			Field field = schema.GetField(SanitaryPara.SanitaryType.ToString());
			entity.Set<string>(field, setSanitaryData.SanitaryType);
			if (setSanitaryData.HotPointVector != null && !setSanitaryData.HotPointVector.IsAlmostEqualTo(new XYZ(0.0, 0.0, 0.0)))
			{
				Field field2 = schema.GetField(SanitaryPara.HotPointVector.ToString());
				entity.Set<XYZ>(field2, setSanitaryData.HotPointVector, 0);
				setSanitaryData.HotAngle = setSanitaryData.HotPointVector.AngleOnPlaneTo(YJKRevitTools.BasisZ(elem), XYZ.BasisZ);
				Field field3 = schema.GetField(SanitaryPara.HotAngle.ToString());
				entity.Set<double>(field3, setSanitaryData.HotAngle, 0);
			}
			if (setSanitaryData.ColdPointVector != null && !setSanitaryData.ColdPointVector.IsAlmostEqualTo(new XYZ(0.0, 0.0, 0.0)))
			{
				Field field4 = schema.GetField(SanitaryPara.ColdPointVector.ToString());
				entity.Set<XYZ>(field4, setSanitaryData.ColdPointVector, 0);
				setSanitaryData.ColdAngle = setSanitaryData.ColdPointVector.AngleOnPlaneTo(YJKRevitTools.BasisZ(elem), XYZ.BasisZ);
				Field field5 = schema.GetField(SanitaryPara.ColdAngle.ToString());
				entity.Set<double>(field5, setSanitaryData.ColdAngle, 0);
			}
			Field field6 = schema.GetField(SanitaryPara.PointOffset.ToString());
			entity.Set<double>(field6, setSanitaryData.PointOffset, 0);
			Field field7 = schema.GetField(SanitaryPara.ColdOffset.ToString());
			entity.Set<double>(field7, setSanitaryData.ColdOffset, 0);
			Field field8 = schema.GetField(SanitaryPara.HotOffset.ToString());
			entity.Set<double>(field8, setSanitaryData.HotOffset, 0);
			Field field9 = schema.GetField(SanitaryPara.Trap.ToString());
			entity.Set<int>(field9, setSanitaryData.Trap, 0);
			Field field10 = schema.GetField(SanitaryPara.DrainEquivalent.ToString());
			entity.Set<double>(field10, setSanitaryData.DrainEquivalent, 0);
			Field field11 = schema.GetField(SanitaryPara.DrainFlow.ToString());
			entity.Set<double>(field11, setSanitaryData.DrainFlow, 0);
			Field field12 = schema.GetField(SanitaryPara.FeedEquivalent.ToString());
			entity.Set<double>(field12, setSanitaryData.FeedEquivalent, 0);
			Field field13 = schema.GetField(SanitaryPara.FeedFlow.ToString());
			entity.Set<double>(field13, setSanitaryData.FeedFlow, 0);
			Field field14 = schema.GetField(SanitaryPara.ShortName.ToString());
			if (field14 != null)
			{
				entity.Set<string>(field14, setSanitaryData.ShortName);
			}
			Field field15 = schema.GetField(SanitaryPara.fieldNew.ToString());
			if (field15 != null)
			{
				entity.Set<string>(field15, setSanitaryData.KeyTerminal);
			}
			Field field16 = schema.GetField("New1");
			if (field16 != null)
			{
				entity.Set<string>(field16, setSanitaryData.TerminalLegendName);
			}
			return entity;
		}

		private Document doc;

		private Selection sel;

		private UIDocument uiDoc;
	}
}
